home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsIII / panorama.c < prev    next >
Text File  |  1992-06-16  |  6KB  |  189 lines

  1. /*
  2.  * Panoramic virtual screen implementation code fragment.
  3.  *
  4.  * Copyright (C) 1991, F. Kenton Musgrave 
  5.  * All rights reserved.
  6.  *
  7.  * This code is an extension of Rayshade 4.0
  8.  * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
  9.  * All rights reserved.
  10.  */
  11.  
  12. RSViewing()
  13. {
  14.     Float magnitude;
  15.     RSMatrix trans;
  16.     Vector eyeOffset;
  17.     int x, y;
  18.  
  19.     VecSub(Camera.lookp, Camera.pos, &Camera.dir);
  20.     Screen.firstray = Camera.dir;
  21.  
  22.     Camera.lookdist = VecNormalize(&Camera.dir);
  23.     if (VecNormCross(&Camera.dir, &Camera.up, &Screen.scrni) == 0.)
  24.         RLerror(RL_PANIC,
  25.             "The view and up directions are identical?\n");
  26.     (void)VecNormCross(&Screen.scrni, &Camera.dir, &Screen.scrnj);
  27.  
  28.     /* construct screen "x" (horizontal) direction vector */
  29.     if (!Options.panorama) {
  30.         /* standard virtual screen setup */
  31.         magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.hfov)) /
  32.                     Screen.xres;
  33.         VecScale(magnitude, Screen.scrni, &Screen.scrnx);
  34.     } else {
  35.         /* For panorama option, we need an array of screen "x" vectors
  36.          * which we will build later in the code.  At this point, we
  37.          * just construct the required rotation matrix (rotations being
  38.          * about the "up" vector) and point the "scrnx" vector to the
  39.          * edge of the screen.
  40.          */
  41.         Camera.lookdist = 1.;
  42.         magnitude = -deg2rad(Camera.hfov);
  43.         Screen.hincr = magnitude / Screen.xres;
  44.         Screen.scrnx = Camera.dir;
  45.             RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,
  46.                 -0.5*magnitude, &trans );
  47.         VecTransform( &Screen.scrnx, &trans );
  48.     }
  49.  
  50.     /* construct screen "y" (vertical) direction vector */
  51.     magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.vfov)) /
  52.                 Screen.yres;
  53.     VecScale(magnitude, Screen.scrnj, &Screen.scrny);
  54.  
  55.     if (!Options.panorama) {
  56.         /* Construct ray direction for standard virtual screen */
  57.         Screen.firstray.x -= 0.5*(Screen.xres*Screen.scrnx.x +
  58.                            Screen.yres*Screen.scrny.x);
  59.         Screen.firstray.y -= 0.5*(Screen.xres*Screen.scrnx.y +
  60.                            Screen.yres*Screen.scrny.y);
  61.         Screen.firstray.z -= 0.5*(Screen.xres*Screen.scrnx.z +
  62.                            Screen.yres*Screen.scrny.z);
  63.     } else {
  64.         /* Panorama option: requires that we allocate & fill horizontal
  65.          * and vertical direction arrays.
  66.          */
  67.         Screen.horizdir = (Vector *)Malloc((Screen.xres+1) *
  68.                            sizeof(Vector));
  69.  
  70.         /* Set eye separation for stereo rendering */
  71.         if (Options.stereo) {
  72.             if (Options.eyesep == UNSET)
  73.                 RLerror(RL_PANIC,
  74.                       "No eye separation specified.\n");
  75.             Screen.eyepts = (Vector *)Malloc((Screen.xres+1) *
  76.                                 sizeof(Vector));
  77.             if (Options.stereo == LEFT)
  78.                 magnitude = .5 * Options.eyesep;
  79.             else
  80.                 magnitude =  -.5 * Options.eyesep;
  81.             eyeOffset.x = magnitude * Screen.scrni.x;
  82.             eyeOffset.y = magnitude * Screen.scrni.y;
  83.             eyeOffset.z = magnitude * Screen.scrni.z;
  84.         }
  85.  
  86.         /* Fill the array of horizontal directions and, if stereo
  87.          * rendering, eyepoints.
  88.          * The horizontal ("x") direction array contains rotations of
  89.          * "scrnx".  Each entry requires construction of an appropriate
  90.          * rotation matrix; rotation again being around the "up" vector.
  91.          */
  92.         for ( x=0; x<=Screen.xres; x++ ) {
  93.             Screen.horizdir[x] = Screen.scrnx;
  94.                 RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,
  95.                     x*Screen.hincr, &trans );
  96.             VecTransform( &Screen.horizdir[x], &trans );
  97.             /* Offset the eyepoints for stereo panorama */
  98.             if (Options.stereo) {
  99.                 Screen.eyepts[x] = eyeOffset;
  100.                 VecTransform( &Screen.eyepts[x], &trans );
  101.                 VecAdd( Screen.eyepts[x], Camera.pos,
  102.                     &Screen.eyepts[x] );
  103.             }
  104.         }
  105.  
  106.         /* The vertical ("y") array varies as the tangent of "scrny". */
  107.         Screen.vertdir = (Vector *)Malloc((Screen.yres+1) *
  108.                           sizeof(Vector));
  109.         for ( y=0; y<=Screen.yres; y++ ) {
  110.             Screen.vertdir[y] = Screen.scrny;
  111.             magnitude = 0.5*Camera.vfov -
  112.                     Camera.vfov * ((Float)y/Screen.yres);
  113.             magnitude = tan(deg2rad(magnitude));
  114.             VecScale(-magnitude, Screen.scrnj, &Screen.vertdir[y]);
  115.         }
  116.     }
  117.  
  118. } /* RSViewing() */
  119.  
  120.  
  121. SampleScreen(x, y, ray, color)
  122. Float x, y;        /* Screen position to sample */
  123. Ray *ray;        /* ray, with origin and medium properly set */
  124. Pixel *color;        /* resulting color */
  125. {
  126.     Float dist;
  127.     HitList hitlist;
  128.     Color ctmp, fullintens;
  129.     extern void ShadeRay();
  130.     int ix, iy;
  131.  
  132.     /*
  133.      * Calculate ray direction.
  134.      */
  135.     Stats.EyeRays++;
  136.     if (Options.panorama) {
  137.         /* Construct ray direction from vectors in tables, 
  138.          * using linear interpolation for jittering.
  139.          */
  140.         ix = (int)x;
  141.         iy = (int)y;
  142.         if (Options.stereo)
  143.             ray->origin = Screen.eyepts[ix];
  144.         ray->dir.x = Screen.horizdir[ix].x +
  145.                  (Screen.horizdir[ix+1].x - Screen.horizdir[ix].x)
  146.                  * (x-ix) +
  147.                  Screen.vertdir[iy].x +
  148.                  (Screen.horizdir[iy+1].x - Screen.horizdir[iy].x)
  149.                  * (y-iy);
  150.         ray->dir.y = Screen.horizdir[ix].y +
  151.                  (Screen.horizdir[ix+1].y - Screen.horizdir[ix].y)
  152.                  * (x-ix) +
  153.                  Screen.vertdir[iy].y +
  154.                  (Screen.horizdir[iy+1].y - Screen.horizdir[iy].y)
  155.                  * (y-iy);
  156.         ray->dir.z = Screen.horizdir[ix].z +
  157.                  (Screen.horizdir[ix+1].z - Screen.horizdir[ix].z)
  158.                  * (x-ix) +
  159.                  Screen.vertdir[iy].z +
  160.                  (Screen.horizdir[iy+1].z - Screen.horizdir[iy].z)
  161.                  * (y-iy);
  162.     } else {
  163.         ray->dir.x = Screen.firstray.x + x*Screen.scrnx.x +
  164.                     y*Screen.scrny.x;
  165.         ray->dir.y = Screen.firstray.y + x*Screen.scrnx.y +
  166.                     y*Screen.scrny.y;
  167.         ray->dir.z = Screen.firstray.z + x*Screen.scrnx.z +
  168.                     y*Screen.scrny.z;
  169.     } 
  170.  
  171.     (void)VecNormalize(&ray->dir);
  172.  
  173.     /*
  174.      * Do the actual ray trace.
  175.      */
  176.     fullintens.r = fullintens.g = fullintens.b = 1.;
  177.     dist = FAR_AWAY;
  178.     hitlist.nodes = 0;
  179.     (void)TraceRay(ray, &hitlist, EPSILON, &dist);
  180.     ShadeRay(&hitlist, ray, dist, &Screen.background, &ctmp, &fullintens);
  181.     color->r = ctmp.r;
  182.     color->g = ctmp.g;
  183.     color->b = ctmp.b;
  184.  
  185. } /* SampleScreen() */
  186.  
  187.  
  188.  
  189.